#pragma once
#include <SetupAPI.h>
#include <Strsafe.h>
#include <Cfgmgr32.h>

struct GenericContext {
	DWORD count;
	DWORD control;
	BOOL  reboot;
	LPCTSTR strSuccess;
	LPCTSTR strReboot;
	LPCTSTR strFail;
};

struct IdEntry {
	LPCTSTR String;     // string looking for
	LPCTSTR Wild;       // first wild character if any
	BOOL    InstanceId;
};

#define EXIT_OK      (0)
#define EXIT_REBOOT  (1)
#define EXIT_FAIL    (2)
#define EXIT_USAGE   (3)

#define INSTANCEID_PREFIX_CHAR _T('@') // character used to prefix instance ID's
#define CLASS_PREFIX_CHAR      _T('=') // character used to prefix class name
#define WILD_CHAR              _T('*') // wild character
#define QUOTE_PREFIX_CHAR      _T('\'') // prefix character to ignore wild characters
#define SPLIT_COMMAND_SEP      _T(":=") // whole word, indicates end of id's

using CallbackFunc = int(*)(
	_In_ HDEVINFO Devs,
	_In_ PSP_DEVINFO_DATA DevInfo,
	_In_ DWORD Index,
	_In_ LPVOID Context
	);
#if 0
typedef int(*CallbackFunc)(
	_In_ HDEVINFO Devs,
	_In_ PSP_DEVINFO_DATA DevInfo,
	_In_ DWORD Index,
	_In_ LPVOID Context
	);
#endif

class CSetupAPIMgr
{
public:
	CSetupAPIMgr();
	~CSetupAPIMgr();

	BOOL Disable(LPCTSTR lpDevice);
	BOOL RemoveGhostDevices();

private:
	IdEntry GetIdType(_In_ LPCTSTR Id);
	BOOL WildCardMatch(_In_ LPCTSTR Item, _In_ const IdEntry & MatchEntry);
	LPTSTR* GetMultiSzIndexArray(_In_ __drv_aliasesMem LPTSTR MultiSz);
	LPTSTR* GetDevMultiSz(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_ DWORD Prop);
	BOOL WildCompareHwIds(_In_ PZPWSTR Array, _In_ const IdEntry & MatchEntry);
	void DelMultiSz(_In_opt_ __drv_freesMem(object) PZPWSTR Array);
	int EnumerateDevices(_In_ LPCTSTR BaseName, _In_opt_ LPCTSTR Machine, _In_ DWORD Flags, _In_ int argc, _In_reads_(argc) PWSTR* argv, _In_ CallbackFunc Callback, _In_ LPVOID Context);
	LPTSTR GetDeviceStringProperty(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_ DWORD Prop);
	BOOL ExcludeHardware(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo);

	static int DeviceControl(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_ DWORD Index, _In_ LPVOID Context);
	static BOOL DumpDeviceWithInfo(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_opt_ LPCTSTR Info);
};

